﻿using LJ.AspNetCore.Abstractions.Pack;
using LJ.Host.Abstractions.DependencyInjection;
using LJ.Host.Abstractions.Pack;
using LJ.Host.Abstractions.Pack.Internal;
using LJ.Host.Abstractions.Thread;
using LJ.Host.Web.Pack.Internal;
using Microsoft.Extensions.DependencyInjection;

namespace LJ.Host.Web.Extensions;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddLJ(this IServiceCollection serviceCollection, IConfiguration configuration)
    {


        serviceCollection.AddHttpContextAccessor();
        serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();


        serviceCollection.AddSingleton<PackBootstrapper>();

        serviceCollection.AddTransient<ICancellationTokenProvider, CancellationTokenProvider>();

        serviceCollection.AddTransient<IConfigProvider, ConfigProvider>();

        var packContext = new AspNetCorePackContext(serviceCollection, configuration);

        var packManager = new PackManager(packContext.ReflectionManager);
        serviceCollection.AddSingleton<IPackManager>(packManager);


        //Startup and Hosted 
        var packServerManager = new PackServerManager(packContext.DependencyManager, packContext.ReflectionManager);
        serviceCollection.AddSingleton<IPackServerManager>(packServerManager);

        serviceCollection.AddSingleton<IPackLifetime, PackLifetime>();

        serviceCollection.AddSingleton<PackBootstrapper>();
        serviceCollection.AddHostedService(sp => sp.GetRequiredService<PackBootstrapper>());
        serviceCollection.AddSingleton<IPackBootstrapper>(sp => sp.GetRequiredService<PackBootstrapper>());


        serviceCollection.AddSingleton<IDependencyInjectionFactory, DependencyInjectionFactory>();

        serviceCollection.AddSingleton<IHybridProvider<IServiceProvider>, HybridProvider<IServiceProvider>>();
        serviceCollection.AddTransient<IHybridProviderHandler<IServiceProvider>, HybridProviderHandler<IServiceProvider>>();

        serviceCollection.AddSingleton<IHybridProvider<CancellationToken>, HybridProvider<CancellationToken>>();
        serviceCollection.AddTransient<IHybridProviderHandler<CancellationToken>, HybridProviderHandler<CancellationToken>>();
        //默认跨域配置
        //https://www.dotnetshare.com/guid/cors.html
        serviceCollection.AddCors(options =>
        {
            options.AddDefaultPolicy(policy =>
            {
                //policy.AllowAnyOrigin()
                //        .AllowAnyHeader()
                //        .AllowAnyMethod();
                policy.WithOrigins()
                  .AllowAnyHeader()
                  .AllowAnyMethod()
                  .AllowCredentials();
            });
        });

        var packs = packManager.GetPacks();
        foreach (var pack in packs)
        {
            pack.Add(packContext);
            if (pack is IAspNetCorePack aspNetCorePack)
            {
                aspNetCorePack.Add(packContext);
            }
        }

        return serviceCollection;
    }
}
